
static struct vmap_area *__find_vmap_area(unsigned long addr, struct rb_root *root)
{
    struct rb_node *n = root->rb_node;

    while (n)
    {
        struct vmap_area *va;

        va = rb_entry(n, struct vmap_area, rb_node);
        if (addr < va->va_start)
            n = n->rb_left;
        else if (addr >= va->va_end)
            n = n->rb_right;
        else
            return va;
    }

    return NULL;
}

static struct vmap_area *find_unlink_vmap_area(unsigned long addr)
{
    struct vmap_node *vn;
    struct vmap_area *va;
    int i, j;

    /*
     * Check the comment in the find_vmap_area() about the loop.
     */
    i = j = addr_to_node_id(addr);
    do
    {
        vn = &vmap_nodes[i];

        spin_lock(&vn->busy.lock);
        va = __find_vmap_area(addr, &vn->busy.root);
        if (va)
            unlink_va(va, &vn->busy.root);
        spin_unlock(&vn->busy.lock);

        if (va)
            return va;
    } while ((i = (i + nr_vmap_nodes - 1) % nr_vmap_nodes) != j);

    return NULL;
}
